import {
  NavigationGuardWithThis,
  NavigationHookAfter,
  RouteLocationNormalized,
  RouteRecordMultipleViews,
  RouteRecordMultipleViewsWithChildren,
  RouteRecordRedirect,
  RouteRecordSingleView,
  RouteRecordSingleViewWithChildren,
  RouterScrollBehavior,
} from "vue-router";
import * as VueRouter from "vue-router";

/**
 * 重写VueRouter相关类型。将 route 类型（RouteRecordRaw）从children属性声明子路由的嵌套形式改为 layout属性声明父路由的扁平形式。
 *
 * type RouteRecordRaw = RouteRecordSingleView | RouteRecordSingleViewWithChildren | RouteRecordMultipleViews | RouteRecordMultipleViewsWithChildren | RouteRecordRedirect
 * */
interface AppRouteRecordSingleView
  extends Omit<RouteRecordSingleView, "children"> {
  layout?: AppRouteRecordRaw;
}

interface AppRouteRecordSingleViewWithChildren
  extends Omit<RouteRecordSingleViewWithChildren, "children"> {
  layout?: AppRouteRecordRaw;
}

interface AppRouteRecordMultipleViews
  extends Omit<RouteRecordMultipleViews, "children"> {
  layout?: AppRouteRecordRaw;
}

interface AppRouteRecordMultipleViewsWithChildren
  extends Omit<RouteRecordMultipleViewsWithChildren, "children"> {
  layout?: AppRouteRecordRaw;
}

interface AppRouteRecordRedirect extends Omit<RouteRecordRedirect, "children"> {
  layout?: AppRouteRecordRaw;
}

/** 路由类型 */
export type AppRouteRecordRaw =
  | AppRouteRecordSingleView
  | AppRouteRecordSingleViewWithChildren
  | AppRouteRecordMultipleViews
  | AppRouteRecordMultipleViewsWithChildren
  | AppRouteRecordRedirect;

export interface AppRoutesDefine {
  [propName: string]: AppRouteRecordRaw;
}

/** 路由元数据 */
export interface AppRouteMeta {
  /** 路由级别的滚动行为 */
  scrollBehavior?: RouterScrollBehavior;

  /**
   * 路由级别的权限控制。
   *
   * 返回值作为vue router的全局前置守卫返回值。默认返回false，
   *
   * 需异步判断时可返回一个Promise。
   * */
  allow?:
    | boolean
    | ((
        to: RouteLocationNormalized,
        from: RouteLocationNormalized,
      ) => boolean | ReturnType<NavigationGuardWithThis<undefined>>);
}

/**
 * 调整后的 RouterOptions
 * */
export interface RouterOptions extends Omit<VueRouter.RouterOptions, "routes"> {
  routes: AppRoutesDefine;
}

/** AppRouter 自定义选项 */
export interface RouterExtraOptions {
  /** 是否显示loading */
  showLoading?: boolean | (() => boolean);
  /** 显示loading的函数 */
  showLoadingFunction?: () => void;
  /** 隐藏loading的函数 */
  hideLoadingFunction?: (routeSuccess: boolean) => void;

  /** 在显示loading后的钩子函数 */
  afterShowLoading?: (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
  ) => void;

  /** 导航是否允许的默认值 */
  allowDefault?:
    | boolean
    | ((
        to: RouteLocationNormalized,
        from: RouteLocationNormalized,
      ) => boolean | ReturnType<NavigationGuardWithThis<undefined>>);

  /** 导航之后 */
  afterNavigation?: NavigationHookAfter;
}
